
package cn.iocoder.yudao.module.api.product.sku.dto;

import cn.hutool.core.util.NumberUtil;
import cn.iocoder.yudao.framework.business.basic.pojo.vo.BaseVO;
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
import cn.iocoder.yudao.module.api.infrastructure.config.ConfigApiV2;
import cn.iocoder.yudao.module.api.infrastructure.config.dto.MemberConfigRespDTO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import static cn.iocoder.yudao.module.api.infrastructure.ConfigConstants.CONFIG_MEMBER;

/**
 * 价格响应 DTO TODO 子类分散的赋值并不优雅，需改进提供统一的赋值方法
 *
 * @author 山野羡民（1032694760@qq.com）
 * @since 2024/12/23
 */
@Tag(name = "价格响应 DTO")
@Data
@Slf4j
public class PriceRespDTO extends BaseVO {

    @Schema(description = "销售价，单位使用：分。如果是零售商家产品，则为零售价；如果是厂家产品，则为批发价。", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    private Integer price;

    @SuppressWarnings("unused")
    public int getPrice() {
        if (price == null || price <= 0) {
            return 0;
        }
        return price;
    }

    @Schema(description = "销售价，单位使用：元", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.01")
    private String priceYuan;

    @SuppressWarnings("unused")
    public String getPriceYuan() {
        return MoneyUtils.fenToYuanStr(getPrice());
    }

    @Schema(description = "成本价，单位使用：分", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
    @JsonIgnore
    private Integer costPrice;

    @SuppressWarnings("unused")
    @JsonIgnore
    public int getCostPrice() {
        if (costPrice == null || costPrice <= 0) {
            return 0;
        }
        return costPrice;
    }

    @Schema(description = "市场价，单位使用：分", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
    @JsonIgnore
    private Integer marketPrice;

    @SuppressWarnings("unused")
    @JsonIgnore
    public int getMarketPrice() {
        if (marketPrice == null || marketPrice <= 0) {
            return getPrice();
        }
        return marketPrice;
    }

    @JsonIgnore
    public double getDiscount() {
        int salePrice = getPrice();
        if (salePrice == 0) {
            return 0;
        }
        int costPrice = getCostPrice();
        if (costPrice == 0) {
            return 10;
        }
        //return (costPrice * 1D / salePrice) * 10;
        return NumberUtil.div(costPrice, salePrice) * 10;
    }

    @Schema(description = "是否支持收益豆全额抵扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
    private boolean supportCryptocurrencyFullDeduction;

    @SuppressWarnings("unused")
    public boolean isSupportCryptocurrencyFullDeduction() {
        // 优惠折扣小于等于5，利润比较可观，则支持全额抵扣
        return getDiscount() <= 5;
    }

    @Schema(description = "厂家零售价，单位使用：分。如果填写了则支持零售，不填则只支持批发。", example = "0")
    private Integer wholesaleForRetailPrice;

    @SuppressWarnings("unused")
    public int getWholesaleForRetailPrice() {
        if (wholesaleForRetailPrice == null || wholesaleForRetailPrice <= 0) {
            return 0;
        }
        return wholesaleForRetailPrice;
    }

    @Schema(description = "厂家零售价，单位使用：元。如果填写了则支持零售，不填则支持批发。", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.01")
    private String wholesaleForRetailPriceYuan;

    @SuppressWarnings("unused")
    public String getWholesaleForRetailPriceYuan() {
        return MoneyUtils.fenToYuanStr(getWholesaleForRetailPrice());
    }

    @Schema(description = "会员价，单位使用：分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    private Integer vipPrice;

    @SuppressWarnings("unused")
    public int getVipPrice() {
        if (vipPrice == null || vipPrice <= 0) {
            return getPrice();
        }
        return vipPrice;
    }

    @Schema(description = "会员价，单位使用：元", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.01")
    private String vipPriceYuan;

    @SuppressWarnings("unused")
    public String getVipPriceYuan() {
        return MoneyUtils.fenToYuanStr(getVipPrice());
    }

    @Schema(description = "用户等级尊享价格，单位使用：元", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    private Integer memberLevelPrice;

    @SuppressWarnings("unused")
    public int getMemberLevelPrice() {
        if (memberLevelPrice == null || memberLevelPrice <= 0) {
            return getPrice();
        }
        return memberLevelPrice;
    }

    @Schema(description = "用户等级优惠价格，单位使用：元", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.01")
    private String memberLevelPriceYuan;

    @SuppressWarnings("unused")
    public String getMemberLevelPriceYuan() {
        return MoneyUtils.fenToYuanStr(getMemberLevelPrice());
    }

    @Schema(description = "1 积分抵扣金额，单位使用：分，0 表示不支持积分抵扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    private Integer pointDeductUnitPrice;

    @SuppressWarnings("unused")
    public int getPointDeductUnitPrice() {
        if (pointDeductUnitPrice == null || pointDeductUnitPrice <= 0) {
            return 0;
        }
        return pointDeductUnitPrice;
    }

    @Schema(description = "积分抵扣金额，单位使用：分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    private String pointDeductPrice;

    @SuppressWarnings("unused")
    public int getPointDeductPrice() {
        return getPointDeductCount() * getPointDeductUnitPrice(); // 确保整数抵扣
    }

    @Schema(description = "积分抵扣金额，单位使用：元", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.01")
    private String pointDeductPriceYuan;

    @SuppressWarnings("unused")
    public String getPointDeductPriceYuan() {
        return MoneyUtils.fenToYuanStr(getPointDeductPrice());
    }

    @Schema(description = "积分抵扣数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    private Integer pointDeductCount;

    @SuppressWarnings("unused")
    public int getPointDeductCount() {
        if (isSupportCryptocurrencyFullDeduction()) {
            log.trace("[getPointDeductCount][支持联盟豆全额抵扣的，不再进行积分抵扣]");
            return 0;
        }
        int _costPrice = getCostPrice();
        if (_costPrice <= 0) {
            log.trace("[getPointDeductCount][成本价小于等于0，不进行积分抵扣]");
            return 0;
        }
        int deductPrice = Math.max(getPrice() - _costPrice, 0);
        if (deductPrice == 0) {
            log.trace("[getPointDeductCount][成本价和销售价相等，不进行积分抵扣]");
            return 0;
        }
        int unitPrice = getPointDeductUnitPrice();
        if (unitPrice <= 0) {
            log.trace("[getPointDeductCount][设置的 1 积分抵扣多少分钱无效]");
            return 0;
        }
        //return (int) (deductPrice * 1D / unitPrice);
        return (int) NumberUtil.div(deductPrice, unitPrice);
    }

    @Schema(description = "1 联盟豆抵扣金额，单位使用：分，0 表示不支持联盟豆抵扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    private Integer cryptocurrencyDeductUnitPrice;

    @SuppressWarnings("unused")
    public int getCryptocurrencyDeductUnitPrice() {
        if (cryptocurrencyDeductUnitPrice == null || cryptocurrencyDeductUnitPrice <= 0) {
            return 0;
        }
        return cryptocurrencyDeductUnitPrice;
    }

    @Schema(description = "联盟豆抵扣金额，单位使用：分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
    private Integer cryptocurrencyDeductPrice;

    @SuppressWarnings("unused")
    public int getCryptocurrencyDeductPrice() {
        return getCryptocurrencyDeductCount() * getCryptocurrencyDeductUnitPrice(); // 确保整数抵扣
    }

    @Schema(description = "联盟豆抵扣金额，单位使用：元", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.01")
    private String cryptocurrencyDeductPriceYuan;

    @SuppressWarnings("unused")
    public String getCryptocurrencyDeductPriceYuan() {
        return MoneyUtils.fenToYuanStr(getCryptocurrencyDeductPrice());
    }

    @Schema(description = "联盟豆抵扣数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    private Integer cryptocurrencyDeductCount;

    @SuppressWarnings("unused")
    public int getCryptocurrencyDeductCount() {
        int _costPrice = getCostPrice();
        if (_costPrice <= 0) {
            log.trace("[getCryptocurrencyDeductCount][成本价小于等于0，不进行联盟豆抵扣]");
            return 0;
        }
        int deductPrice;
        if (isSupportCryptocurrencyFullDeduction()) {
            deductPrice = getPrice();
            log.trace("[getCryptocurrencyDeductCount][支持联盟豆全额抵扣的，抵扣全部销售价]");
        } else {
            deductPrice = Math.max(getPrice() - _costPrice, 0);
            log.trace("[getCryptocurrencyDeductCount][不支持联盟豆全额抵扣的，计算销售价和成本价之间的差值]");
        }
        if (deductPrice == 0) {
            log.trace("[getCryptocurrencyDeductCount][成本价和销售价相等，不进行联盟豆抵扣]");
            return 0;
        }
        int unitPrice = getCryptocurrencyDeductUnitPrice();
        if (unitPrice <= 0) {
            log.trace("[getCryptocurrencyDeductCount][设置的 1 联盟豆抵扣多少分钱无效]");
            return 0;
        }
        //return (int) (deductPrice * 1D / unitPrice);
        return (int) NumberUtil.div(deductPrice, unitPrice);
    }

    /**
     * 计算积分及联盟豆抵扣价格之前，必须先调用本方法设置计量单位
     */
    public void setDeductUnitPrice(ConfigApiV2 configApiV2) {
        int pointDeductUnitPrice = 0;
        int cryptocurrencyDeductUnitPrice = 0;
        MemberConfigRespDTO config = configApiV2.getConfig(CONFIG_MEMBER, MemberConfigRespDTO.class);
        if (!config.isPointDeductDisable()) {
            pointDeductUnitPrice = config.getPointTradeDeductUnitPrice();
        }
        if (!config.isCryptocurrencyDeductDisable()) {
            cryptocurrencyDeductUnitPrice = config.getCryptocurrencyTradeDeductUnitPrice();
        }
        setPointDeductUnitPrice(pointDeductUnitPrice);
        setCryptocurrencyDeductUnitPrice(cryptocurrencyDeductUnitPrice);
    }

}